package jpaperwork.meta.transformer;

import jpaperwork.meta.descriptor.Aggregation;
import jpaperwork.meta.descriptor.DiscriminatedType;
import jpaperwork.meta.descriptor.Field;
import jpaperwork.meta.descriptor.Flat;
import jpaperwork.meta.descriptor.Polymorphism;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: fleipold
 * Date: Jul 24, 2009
 * Time: 4:34:37 PM
 */
public class RequestFormReader implements FormReader {
    public Object readFieldValue(Field field, Object transformee) {
        Map<String, Object> request = (Map) transformee;
        Map<String, Object> mappedRequest = new HashMap();
        for (String key: request.keySet()){
            if (key.split("\\.|:|_")[0].equals(field.getName())){
                String localKey = key.substring(field.getName().length());
                if (localKey.startsWith(".") ||  localKey.startsWith("_")){
                    localKey = localKey.substring(1);
                }
                if (localKey.equals("")) {
                	String[] value = (String[])request.get(key);
                	if (((Flat)field.getType()).isArray())
                		return value;
                	else {                		
						if (value.length > 1) {
                			throw new RuntimeException("Got more than one value for flat scalar field " +field );                			                			
                		}
						return value[0];												
                	}
                		
                }
                mappedRequest.put(localKey, request.get(key));
            }

        }
        if (mappedRequest.isEmpty()){
            return null;
        }
        return mappedRequest;

    }

    
    public List readCollectionValues(Aggregation aggregation, Object transformee) {
        Map<String, Object> request = (Map) transformee;
        List transformedRequests = new ArrayList();
        
        int index = 0;
        boolean found = false;
        do {
           found = false;
            Map<String, Object> mappedRequest = new HashMap();
            for (String key: request.keySet()){
                if (key.split("\\.")[0].equals(""+index)){
                    found =true;
                    mappedRequest.put(key.substring(key.indexOf(".")+1), request.get(key));
                }

            }
            index ++;
            if (found)
                transformedRequests.add(mappedRequest);

        }  while (found);
        return transformedRequests;


    }

    public PolymorphicValue determineType(Polymorphism polymorphism, Object transformee) {
         Map<String, Object> request = (Map) transformee;
        Map<String, Object> mappedRequest = new HashMap();
        for (DiscriminatedType type: polymorphism.getTypes()){
            if (((String[])request.get(":TYPE"))[0].equals( type.getDiscriminator())){
                for (String key : request.keySet()){
                    if (key.startsWith(type.getDiscriminator() + ":")){
                        String transformedKey = key.substring(key.indexOf(":") + 1);
                        mappedRequest.put(transformedKey, request.get(key));
                    }
                }

                return new PolymorphicValue(type, mappedRequest);
            }

        }
        throw new RuntimeException("Could not resolve type");
        //todo nicer error message

    }
}
